<?php

Raise::load('core.RaiseStaticClass');
Raise::load('core.text.html.RaiseHtmlDocType');
Raise::load('core.text.html.RaiseHtmlTag');
Raise::load('core.collection.RaiseCollection');
Raise::load('core.text.RaiseText');
Raise::load('core.helper.convert.RaiseConvert');

/**
 * RaiseHtml helper class
 * Helps to create HTML and XHTML tags
 *
 * @author Sam-Mauris Yong / hellclanner at live dot com
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package phpraise.core.text.html
 * @since 1.2
 */
class RaiseHtml extends RaiseStaticClass {

    /**
     * The currently selected document type
     * @var string String constant from RaiseHtmlDocType by default
     * @static
     */
    public static $selectedDocType = RaiseHtmlDocType::XHTML1_1;

    /**
     * Create a RaiseHtmlTag
     * @param string $tagName The HTML tag name
     * @param string $value The content/value of the HTML tag
     * @param array|RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function tag($tagName, $value = '', $attributes = array()){
        $tag = new RaiseHtmlTag($tagName, $value, $attributes);
        return $tag;
    }

    /**
     * Create a hyperlink HTML tag &lt;a>
     * @param string $text The text of the HTML tag
     * @param string|RaiseUrl $url The URL of the hyperlink
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function hyperlink($text, $url, $attributes = array()){
        $attributes = new RaiseCollection($attributes);
        if(is_object($url)){
            $url = RaiseConvert::to(RaiseConvert::TO_STRING, $url);
        }
        $attributes->add('href', $url);
        return self::tag('a', $text, $attributes);
    }

    /**
     * Create a breakline HTML tag &lt;br /&gt;
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function breakLine($attributes = array()){
        return self::tag('br', '', $attributes);
    }

    /**
     * Create a script block HTML tag &lt;script>
     * @param string $code The Javascript code
     * @param RaiseCollection $attributes Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function script($code, $attributes = array()){
        if(self::isXHTMLSelected() && strpos($code, '<![CDATA[') === false){
            $code = '/* <![CDATA[ */ ' . $code . ' /* ]]> */';
        }
        return self::tag('script', $code, $attributes);
    }


    /**
     * Create a hyperlink HTML tag &lt;script src="...">
     * @param string $src The Javascript file to include
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function scriptFile($src, $attributes = array()){
        $attributes = new RaiseCollection($attributes);
        $attributes->add('src', $src);
        return self::tag('script', '', $attributes);
    }

    /**
     * Create a hyperlink HTML tag &lt;title>
     * @param string $title
     * @return RaiseHtmlTag
     * @static
     */
    public static function title($title){
        return self::tag('title', RaiseHtml::encode($title));
    }

    /**
     * Create a section HTML tag &lt;div>
     * @param string $content Content of the HTML div tag
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function div($content, $attributes = array()){
        return self::tag('div', $content, $attributes);
    }

    /**
     * Create a spanning label HTML tag &lt;span>
     * @param string $content Content of the HTML span tag
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function span($content, $attributes = array()){
        return self::tag('span', $content, $attributes);
    }
    
    /**
     * Create a style block HTML tag &lt;style>
     * @param string $style CSS Codes
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function css($style, $attributes = array()){
        return self::tag('style', $style, $attributes);
    }
    
    /**
     * Create a CSS link HTML tag &lt;link>
     * @param string $style CSS Codes
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function cssFile($src, $attributes = array()){
        if($attributes instanceof RaiseCollection){
            $attributes = $attributes->toArray();
        }
        $attributes = array_merge($attributes, array('rel'=>'stylesheet', 'type' => 'text/css', 'href' => $src));
        return self::tag('link', '', $attributes);
    }

    /**
     * Create an image HTML tag &lt;img>
     * @param string $src The image file URL
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function image($src, $attributes = array()){
        $attributes = new RaiseCollection($attributes);
        $attributes->add('src', $src);
        return self::tag('img', '', $attributes);
    }

    /**
     * Create a preformat HTML tag &lt;pre>
     * @param string $content The content of the preformat block
     * @param RaiseCollection $attributes (optional) Attributes of the HTML tag
     * @return RaiseHtmlTag
     * @static
     */
    public static function preformat($content, $attributes = array()){
        return self::tag('pre', $content, $attributes);
    }
    
    /**
     * Create a HTML list
     * @param array|Collection $list The array or collection
     * @param string $prefix (optional) The string that will start the list item. Defaults to &lt;li>
     * @param string $suffix (optional) The string that will end the list item. Defaults to &lt;/li>
     * @return string
     */
    public static function listWrap($list, $prefix = '<li>', $suffix = '</li>'){
        $output = '';
        foreach($list as $item){
            $output .= $prefix . $item . $suffix;
        }
        return $output;
    }
    
    /**
     * Convert all characters with special significance in HTML to their respective HTML entities in a string.
     * @param string|RaiseString $s The string to encode
     * @return string
     * @link http://php.net/htmlspecialchars
     * @static
     */
    public static function encode($s){
        return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
    }
    
    /**
     * Convert special HTML entities back to characters
     * @param string|RaiseString $s The string to decode
     * @return string
     * @link http://php.net/htmlspecialchars-decode
     * @static
     */
    public static function decode($s){
        return htmlspecialchars_decode($s, ENT_QUOTES);
    }

    /**
     * Determine whether the selected doctype is XHTML or not
     * @return boolean
     * @static
     */
    public static function isXHTMLSelected(){
        switch(self::$selectedDocType){
            case RaiseHtmlDocType::XHTML1_1:
            case RaiseHtmlDocType::XHTML_BASIC_1_1:
            case RaiseHtmlDocType::XHTML1_STRICT:
            case RaiseHtmlDocType::XHTML1_TRANSITIONAL:
            case RaiseHtmlDocType::XHTML1_FRAMESET:
                return true;
        }
        return false;
    }

    /**
     * Determine whether the selected doctype is HTML or not
     * @return boolean
     */
    public static function isHTMLSelected(){
        switch(self::$selectedDocType){
            case RaiseHtmlDocType::HTML4_01_STRICT:
            case RaiseHtmlDocType::HTML4_01_TRANSITIONAL:
            case RaiseHtmlDocType::HTML4_01_FRAMSET:
            case RaiseHtmlDocType::HTML5:
                return true;
        }
        return false;
    }
}
